﻿#include <learn/topo/topo_builder.h>
#include <learn/topo/topo_coedge.h>
#include <learn/topo/topo_edge.h>
#include <learn/topo/topo_wire.h>

using namespace xi;
using namespace xi::topo;

Topo_Coedge::Topo_Coedge()
    : Topo_Shape(), m_twin(nullptr), m_next(nullptr), m_prev(nullptr), m_wire(nullptr), m_edge(nullptr),
      m_dir(Topo_Dir::Forward)
{
}

Topo_Coedge::~Topo_Coedge()
{
    Topo_Builder builder;

    // 移除 twin
    if (m_twin != nullptr)
    {
        m_twin->twin() = nullptr;
        m_twin->edge() = nullptr;
        delete m_twin;
        m_twin = nullptr;
    }

    // 移除 edge
    if (m_edge != nullptr)
    {
        m_edge->coedge() = nullptr;
        builder.remove_edge(m_edge);
        m_edge = nullptr;
    }

    // 移除 loop
    if (m_wire != nullptr)
    {
        // 这里不能将 loop->coedge() 置空，因为需要 loop 遍历 coedge 移除 loop 指针
        builder.remove_wire(m_wire);
        m_wire = nullptr;
    }

    // 断开连接
    if (m_next != nullptr)
        m_next->prev() = nullptr;
    if (m_prev != nullptr)
        m_prev->next() = nullptr;

    m_next = nullptr;
    m_prev = nullptr;
}

Topo_Coedge *&Topo_Coedge::twin()
{
    return m_twin;
}

Topo_Coedge *&Topo_Coedge::prev()
{
    return m_prev;
}

Topo_Coedge *&Topo_Coedge::next()
{
    return m_next;
}

Topo_Wire *&Topo_Coedge::wire()
{
    return m_wire;
}

Topo_Edge *&Topo_Coedge::edge()
{
    return m_edge;
}

Topo_Dir Topo_Coedge::dir() const
{
    return m_dir;
}

bool Topo_Coedge::is_boundary() const
{
    // 如果此半边不属于任何 wire，或者所属 wire 是边界，则一定在边界上
    return m_wire == nullptr || m_wire->loop() == Topo_Loop::Boundary;
}